package com.shop.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.entity.dto.WeChatOrders.UserOrdersPayDto;
import com.shop.entity.dto.WeChatOrders.UserOrdersSaveDto;
import com.shop.entity.pojo.Address;
import com.shop.entity.pojo.Cart;
import com.shop.entity.pojo.Orders;
import com.shop.entity.pojo.OrdersDetail;
import com.shop.entity.vo.OrdersVo;
import com.shop.user.config.WebSocket;
import com.shop.user.mapper.AddressMapper;
import com.shop.user.mapper.CartMapper;
import com.shop.user.mapper.OrdersDetailMapper;
import com.shop.user.mapper.OrdersMapper;
import com.shop.user.mapper.vo.OrdersVoMapper;
import com.shop.user.service.OrdersService;
import com.shop.utils.common.enums.Code;
import com.shop.utils.common.enums.Message;
import com.shop.utils.common.result.Result;
import com.shop.utils.config.BaseContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService{

    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrdersDetailMapper ordersDetailMapper;
    @Autowired
    private OrdersVoMapper ordersVoMapper;
    @Autowired
    private WebSocket webSocket;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AddressMapper addressMapper;

    @Override
    public Result addOrders(UserOrdersSaveDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        Long userId = BaseContext.getCurrentId();
        if (userId==null) {
            return Result.errorResult(Code.NEED_LOGIN);
        }
        String k =Message.WeChat_Key_User_Orders+userId;
        String k2 =Message.WeChat_Key_User_Cart+userId;
        redisTemplate.delete(k2);
        redisTemplate.delete(k);
        List<Cart> checkCart = cartMapper.selectList(Wrappers.<Cart>lambdaQuery().eq(Cart::getUserId, userId));
        if (checkCart==null&&checkCart.size()==Message.Check_Int_Null) {
            return Result.errorResult(Code.DATA_NOT_EXIST);
        }
        String ordersId="JJ_shop"+ String.valueOf(System.currentTimeMillis());
        Orders checkOrders = saveOrders(dto, userId, ordersId);
        OrdersDetail checkDetail = saveOrdersDetail(ordersId,checkCart);
        if (checkOrders==null) {
            ordersDetailMapper.deleteById(checkDetail);
            return Result.errorResult(Code.SERVER_ERROR);
        }
        if (checkOrders==null) {
            ordersMapper.deleteById(checkOrders);
            return Result.errorResult(Code.SERVER_ERROR);
        }
//        Map map = new HashMap();
//        map.put("orders_time", checkOrders.getSaveTime());
//        map.put("orders_state", checkOrders.getOrdersState());
//        map.put( "orders_id" , ordersId);
        webSocket.sendToAllClient(ordersId);
        redisTemplate.delete(k);
        redisTemplate.delete(k2);
        return Result.okResult(checkOrders);
    }

    @Override
    public Result<List<OrdersVo>> getUserOrders() {
        Long userId = BaseContext.getCurrentId();
        if (userId==null) {
            return Result.errorResult(Code.NEED_LOGIN);
        }
        String k =Message.WeChat_Key_User_Orders+userId;
        List<OrdersVo> check = (List<OrdersVo>) redisTemplate.opsForValue().get(k);
        if (check!=null&&check.size()> Message.Check_Int_Null) {
            return Result.okResult(check);
        }
        List<OrdersVo> v = ordersVoMapper.getOrders(userId);
        redisTemplate.opsForValue().set(k,v,1, TimeUnit.HOURS);
        return Result.okResult(v);

    }

    @Override
    public Result payOrders(UserOrdersPayDto dto) {
        if (dto==null) {
            return Result.errorResult(Code.PARAM_REQUIRE);
        }
        Long userId = BaseContext.getCurrentId();
        if (userId==null) {
            return Result.errorResult(Code.NEED_LOGIN);
        }
        Orders check = ordersMapper.selectOne(Wrappers.<Orders>lambdaQuery()
                .eq(Orders::getOrdersId, dto.getOrdersId())
                .eq(Orders::getUserId, userId));
        if (check==null) {
            return Result.errorResult(Code.DATA_NOT_EXIST);
        }
        Orders orders=new Orders();
        orders= orders.builder()
                .id(check.getId())
                .ordersState(Message.Orders_State_Picking).build();
        ordersMapper.updateById(orders);

        return Result.okResult(Code.SUCCESS);
    }

    @Async
    public Orders saveOrders(UserOrdersSaveDto dto,Long userId,String ordersId){
        Orders orders=new Orders();
        Double allPrice = cartMapper.getAllPrice(userId);
        if (dto.getChoose().equals(Message.WeChat_Save_Orders_Choose_Himself)) {
            orders= orders.builder()
                    .userId(userId)
                    .userName(dto.getUserName())
                    .userPhone(dto.getUserPhone())
                    .ordersId(ordersId)
                    .ordersPrice(allPrice)
                    .ordersMode(Message.WeChat_Orders_Choose_Himself)
                    .addressId(null)
                    .ordersMemo(dto.getOrdersMemo())
                    .saveTime(String.valueOf(LocalDateTime.now())).build();
        } else if (dto.getChoose().equals(Message.WeChat_Save_Orders_Choose_Takeaway)) {
            List<Address> checkAddress = addressMapper.selectList(Wrappers.<Address>lambdaQuery()
                    .eq(Address::getId, dto.getAddressId()));
            if (checkAddress==null
                    &&checkAddress.size()== Message.Check_Int_Null
                    ||dto.getAddressId()==null) {
                return null;
            }
            double price=allPrice+10;
            orders= orders.builder()
                    .userId(userId)
                    .userName(dto.getUserName())
                    .userPhone(dto.getUserPhone())
                    .ordersId(ordersId)
                    .ordersPrice(price)
                    .ordersMode(Message.WeChat_Orders_Choose_Takeaway)
                    .addressId(dto.getAddressId())
                    .ordersMemo(dto.getOrdersMemo())
                    .saveTime(String.valueOf(LocalDateTime.now())).build();
        }else {
            return null;
        }

        boolean testOrders = ordersMapper.addCart(orders);
        if (!testOrders) {
            return null;
        }
        return orders;
    }

    @Async
    public OrdersDetail saveOrdersDetail(String ordersId,List<Cart> carts){
        OrdersDetail detail=new OrdersDetail();
        for (Cart cart : carts) {
            detail.setWaresName(cart.getWaresName());
            detail.setStyleName(cart.getStyleName());
            detail.setCostMessage(cart.getCostMessage());
            detail.setCostPrice(cart.getCostPrice());
            detail.setWaresNumber(cart.getWaresNumber());
            detail.setOrdersId(ordersId);

            int insert = ordersDetailMapper.saveOrdersDetail(detail);
            if (insert==Message.Check_Int_False) {
                return null;
            }
            int delete = cartMapper.deleteById(cart.getId());
            if (delete==Message.Check_Int_False) {
                return null;
            }
        }
        return detail;
    }

}




